package com.zhentao.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhentao.classManager.dto.ClassStudentDto;
import com.zhentao.classManager.dto.ExaminationDto;
import com.zhentao.classManager.dto.SAnswerDto;
import com.zhentao.classManager.pojo.SClass;
import com.zhentao.classManager.pojo.SLevel;
import com.zhentao.classManager.pojo.TUser;
import com.zhentao.classManager.pojo.excel.ExcelClass;
import com.zhentao.classManager.pojo.vo.ClassVo;
import com.zhentao.classManager.pojo.vo.ExaminationVo;
import com.zhentao.classManager.pojo.vo.PaperInfoVo;
import com.zhentao.classManager.pojo.vo.SAnswerExamInfoVo;
import com.zhentao.domain.SAnswer;
import com.zhentao.domain.SErrorBook;
import com.zhentao.domain.SLearningProgress;
import com.zhentao.domain.SStudentTree;
import com.zhentao.domain.vo.TuserVO;
import com.zhentao.mapper.*;
import com.zhentao.result.Result;
import com.zhentao.service.SClassService;
import com.zhentao.service.SLearningProgressService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.zhentao.utils.DetectionUtil.calculateEditDistanceNormalized;
import static com.zhentao.utils.DetectionUtil.calculateScore;

/**
* @author song-xinhang
* @description 针对表【s_class】的数据库操作Service实现
* @createDate 2024-07-24 10:08:50
*/
@Service
@Transactional
public class SClassServiceImpl extends ServiceImpl<SClassMapper, SClass>
    implements SClassService{
    @Resource
    private SClassMapper sClassMapper;
    @Resource
    private TUserMapper tUserMapper;
    @Resource
    private SErrorBookMapper sErrorBookMapper;
    @Resource
    private SStudentTreeMapper sStudentTreeMapper;
    @Resource
    private SLevelMapper sLevelMapper;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    @Resource
    private SAnswerMapper sAnswerMapper;
    @Resource
    private SLearningProgressMapper sLearningProgressMapper;

    @Override
    public Result selectClassAll(ClassVo classVo) {
        // 条件查询班级信息
        PageHelper.startPage(classVo.getPageNum(),classVo.getPageSize());
        List<ClassVo> studentVos = sClassMapper.selectClassAll(classVo);
        PageInfo<ClassVo> classVoPageInfo = new PageInfo<>(studentVos);
        return Result.OK(classVoPageInfo);
    }

    @Override
    public Result selectStudentByClass(ClassStudentDto studentDto) {
        //分页
        PageHelper.startPage(studentDto.getPageNum(),studentDto.getPageSize());
        // 查询班级所有学生
        List<TUser> tUsers = tUserMapper.selectList(Wrappers.<TUser>lambdaQuery().eq(TUser::getClassId, studentDto.getClassId()));
        PageInfo<TUser> tUserPageInfo = new PageInfo<>(tUsers);
        return Result.OK(tUserPageInfo);
    }

    @Override
    public Result classAddOrEdit(SClass sClass) {
        SStudentTree sStudentTreePojo = new SStudentTree();
        // 判断id是否为空，如果为空是添加，不为空则修改
        if (sClass.getClassId() == null) {
            // 通过班级名字查询如果重复则不能添加
            SClass sClass2 = sClassMapper.selectOne(Wrappers.<SClass>lambdaQuery().eq(SClass::getClassName, sClass.getClassName()));
            if (sClass2 != null) {
                return Result.ERROR("班级已存在，请重新输入");
            }
            // 判断老师具体带多少个班，每个老师最多可以带两个班
            if (sClass.getTeacherId() != -1){
                List<SClass> sClasses = sClassMapper.selectList(Wrappers.<SClass>lambdaQuery().eq(SClass::getTeacherId, sClass.getTeacherId()));
                if (sClasses.size() >= 2) {
                    return Result.ERROR("该老师已带两个班，不能添加");
                }
            }
            sClassMapper.insert(sClass);
            // 添加后查询添加班级的整条数据
            SClass sClass1 = sClassMapper.selectById(sClass.getClassId());
            // 查询具体阶段所有信息
            SLevel sLevel = sLevelMapper.selectById(sClass1.getLevelId());
            // 查询阶段树
            SStudentTree sStudentTree = sStudentTreeMapper.selectOne(Wrappers.<SStudentTree>lambdaQuery().eq(SStudentTree::getName, sLevel.getLevelName()));
            // 给要添加到阶段树的数据赋值
            sStudentTreePojo.setClassId(sClass1.getClassId());
            sStudentTreePojo.setName(sClass1.getClassName());
            sStudentTreePojo.setParentId(sStudentTree.getId()); // 设置阶段树的ID
            sStudentTreeMapper.insert(sStudentTreePojo);
            return Result.OKMess("添加成功");
        } else {
            // 判断老师具体带多少个班，每个老师最多可以带两个班
            if (sClass.getTeacherId() != -1) {
                TUser tUser = tUserMapper.selectById(sClass.getTeacherId());
                List<SClass> sClasses = sClassMapper.selectList(Wrappers.<SClass>lambdaQuery()
                        .eq(SClass::getTeacherId, tUser.getUserId()));
                // 检查是否修改的是该老师自己负责的班级
                boolean isModifyingOwnClass = sClasses.stream()
                        .anyMatch(sc -> sc.getClassId().equals(sClass.getClassId()));
                if (!isModifyingOwnClass && sClasses.size() >= 2) {
                    return Result.ERROR("该老师已带两个班，不能修改");
                }
            }
            //查看所选的阶段是否和具体阶段相符
            SLearningProgress sLearningProgress = sLearningProgressMapper.selectOne(Wrappers.<SLearningProgress>lambdaQuery().eq(SLearningProgress::getId, sClass.getLpId()));
            if (sLearningProgress.getLevelId() != sClass.getLevelId()){
                return Result.ERROR("所选阶段和具体阶段不符，请重新选择");
            }
            // 更新班级信息
            sClassMapper.updateById(sClass);
            // 修改后查询修改班级的整条数据
            SClass updatedSClass = sClassMapper.selectById(sClass.getClassId());
            // 查询具体阶段所有信息
            SLevel sLevel = sLevelMapper.selectById(updatedSClass.getLevelId());
            // 查询阶段树
            SStudentTree sStudentTree = sStudentTreeMapper.selectOne(Wrappers.<SStudentTree>lambdaQuery()
                    .eq(SStudentTree::getName, sLevel.getLevelName()));
            // 根据班级名查询阶段树编号
            List<SStudentTree> sStudentTrees = sStudentTreeMapper.selectList(Wrappers.<SStudentTree>lambdaQuery()
                    .eq(SStudentTree::getName, updatedSClass.getClassName()));
            // 遍历并更新阶段树信息
            for (SStudentTree studentTree : sStudentTrees) {
                // 更新阶段树的相关数据
                studentTree.setParentId(sStudentTree.getId()); // 设置阶段树的ID
                studentTree.setName(updatedSClass.getClassName());
                sStudentTreeMapper.updateById(studentTree);
            }
            return Result.OKMess("修改成功");
        }
    }

    @Override
    public Result deleteBatchClass(Integer[] classId) {
        //遍历数据查询如果班级里面存在学生则不能删除
        List<TUser> users = new ArrayList<>();
        for (Integer id : classId) {
            List<TUser> tUsers = tUserMapper.selectList(Wrappers.<TUser>lambdaQuery().eq(TUser::getClassId, id));
            users.addAll(tUsers);
        }
        if (users.size() > 0){
            return Result.ERROR("该班级存在学生，不能删除");
        }
        //查询出要删除的班级信息
        List<SClass> sClasses = sClassMapper.selectList(Wrappers.<SClass>lambdaQuery().in(SClass::getClassId, classId));
        //定义一个空集合存放要删除的阶段树编号
        List<Integer> list = new ArrayList<>();
        //遍历查询出的班级信息
        for (SClass sClass1 : sClasses) {
            //根据班级名查询阶段树编号
            List<SStudentTree> sStudentTrees = sStudentTreeMapper.selectList(Wrappers.<SStudentTree>lambdaQuery().eq(SStudentTree::getName, sClass1.getClassName()));
            //将查询出来的班级编号存入空集合
            for (SStudentTree sStudentTree : sStudentTrees) {
                list.add(sStudentTree.getId());
            }
        }
        //根据编号删除阶段树信息
        sStudentTreeMapper.deleteBatchIds(list);
        //删除班级信息
        sClassMapper.deleteBatchIds(Arrays.asList(classId));
        return Result.OKMess("删除成功");
    }

    @Override
    public Result selectTeacherAll() {
        //查询所有老师信息
        List<TuserVO> list = tUserMapper.selectTeacherAll();
        return Result.OK(list);
    }

    @Override
    public void exportClass(HttpServletResponse response) throws IOException {
        List<ExcelClass> list = tUserMapper.selectTeacher();
        // 设置响应内容类型为 Excel 文件
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 对文件名进行编码处理
        String fileName = "班级信息.xlsx";
        String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
        // 设置响应头部
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + encodedFileName);
        // 使用 EasyExcel 将数据写入输出流
        EasyExcel.write(response.getOutputStream(), ExcelClass.class).sheet("班级信息").doWrite(list);
    }

    @Override
    public Result changeClass(Integer userId, Integer classId) {
        //查询学生原班级
         TUser tUser = tUserMapper.selectById(userId);
         if (tUser.getClassId() == classId){
             return Result.ERROR("学生已经在该班级，无需修改");
         }
         //修改学生班级
         tUser.setClassId(classId);
        tUserMapper.updateById(tUser);
        return Result.OKMess("调换成功");
    }

    @Override
    public Result removeClassStudent(Integer userId) {
        TUser tUser = tUserMapper.selectOne(Wrappers.<TUser>lambdaQuery().eq(TUser::getUserId, userId));
        tUser.setClassId(-1);
        tUserMapper.updateById(tUser);
        return Result.OKMess("移除成功");
    }

    @Override
    public Result classExaminationInfo(ExaminationDto examinationDto) {
        //分页查询考试信息
        PageHelper.startPage(examinationDto.getPageNum(), examinationDto.getPageSize());
        //查询所有考试信息
        List<ExaminationVo> examinationVOList = tUserMapper.selectExaminationInfo(examinationDto);
        PageInfo<ExaminationVo> pageInfo = new PageInfo<>(examinationVOList);
        //查询本厂考试答题卡是否存在
        for (ExaminationVo examinationVo : examinationVOList) {
            //单选题总分
            String radioCount = examinationVo.getRadioCount();
            String[] radioParts = radioCount.split("_");
            int radioQuestionCount = Integer.parseInt(radioParts[0]);
            int radioQuestionScore = Integer.parseInt(radioParts[1]);
            //多选题总分
            String checkCount = examinationVo.getCheckCount();
            String[] checkParts = checkCount.split("_");
            int checkQuestionCount = Integer.parseInt(checkParts[0]);
            int checkQuestionScore = Integer.parseInt(checkParts[1]);
            //判断题总分
            String judgmentCount = examinationVo.getJudgmentCount();
            String[] judgmentParts = judgmentCount.split("_");
            int judgmentQuestionCount = Integer.parseInt(judgmentParts[0]);
            int judgmentQuestionScore = Integer.parseInt(judgmentParts[1]);
            //简答题总分
            String textCount = examinationVo.getTextCount();
            String[] textParts = textCount.split("_");
            int textQuestionCount = Integer.parseInt(textParts[0]);
            int textQuestionScore = Integer.parseInt(textParts[1]);
            examinationVo.setTotalScore(textQuestionCount * textQuestionScore+ radioQuestionCount * radioQuestionScore + checkQuestionCount * checkQuestionScore + judgmentQuestionCount * judgmentQuestionScore);
            //及格分数是总分的80%
            examinationVo.setPassScore((int) (examinationVo.getTotalScore() * 0.8));
            //将查询出的考试场次编号给dto赋值
            examinationDto.setTestInfoId(examinationVo.getId());
            List<SAnswer> sAnswer = sAnswerMapper.selectList(Wrappers.<SAnswer>lambdaQuery().eq(SAnswer::getUId, examinationDto.getUId()).eq(SAnswer::getTestinfoId, examinationDto.getTestInfoId()));
            //遍历答题卡集合
            for (SAnswer answer : sAnswer) {
                //将答题卡编号给vo赋值
                examinationVo.setAnswerId(answer.getId());
            }
        }
        return Result.OK(pageInfo);
    }

    @Override
    public Result examinationQuestion(Integer examinationId) {
        // 查询所有考试信息以及题目
        List<PaperInfoVo> list = tUserMapper.examinationQuestion(examinationId);
        // 遍历集合查看题目数量是否充足，如果不足给出提示
        for (PaperInfoVo paperInfoVo : list) {
            if (paperInfoVo == null || paperInfoVo.getQuestion().isEmpty()) {
                return Result.ERROR("本场考试，题目数量不足");
            }
        }
        // 根据题目类型进行分组
        Map<Integer, List<PaperInfoVo>> groupedByType = list.stream()
                .collect(Collectors.groupingBy(PaperInfoVo::getTypeId));
        // 打乱每个类型的题目集合顺序
        groupedByType.forEach((type, questions) -> Collections.shuffle(questions));
        // 将打乱后的题目重新整合成一个 List
        List<PaperInfoVo> shuffledList = groupedByType.values().stream()
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
        // 遍历打乱后的集合将数据存入 Redis
        for (PaperInfoVo paperInfoVo : shuffledList) {
            // 将题目以及答案存入 Redis 方便之后进行比对
            redisTemplate.opsForSet().add(paperInfoVo.getId().toString(), paperInfoVo.getAnswerTxt());
            // 设置过期时间为 30 天
            redisTemplate.expire(paperInfoVo.getId().toString(), 30, TimeUnit.DAYS);
        }
        return Result.OK(shuffledList);
    }

    int score;
    public void compareAndScore(PaperInfoVo paperInfoVo, RedisTemplate<String, Object> redisTemplate, int maxScore) {
        // 获取Redis中存储的答案集合
        Set<Object> correctAnswers = redisTemplate.opsForSet().members(paperInfoVo.getId().toString());
        //将学生答案存入redis
        redisTemplate.opsForSet().add(paperInfoVo.getUserId()+","+paperInfoVo.getExamId().toString()+","+paperInfoVo.getId(),paperInfoVo.getStuAnswer().toString());
        //设置缓存过期时间为30天
        redisTemplate.expire(paperInfoVo.getUserId()+","+paperInfoVo.getExamId().toString()+","+paperInfoVo.getId(), 30, TimeUnit.DAYS);
        // 检查学生答案是否为空
        if (StringUtils.isNotBlank(paperInfoVo.getStuAnswer())) {
            // 检查学生答案是否与正确答案相等
            if (correctAnswers != null && correctAnswers.contains(paperInfoVo.getStuAnswer())) {
                // 如果答案正确，则增加2分
                score += 2;
                // 确保分数不超过最大分值
                if (score > maxScore) {
                    score = maxScore;
                }
            } else {
                // 如果答案错误，则记录错题
                SErrorBook sWrongQuestion = new SErrorBook();
                sWrongQuestion.setQuestionId(paperInfoVo.getId());
                sWrongQuestion.setUserId(paperInfoVo.getUserId());
                sErrorBookMapper.insert(sWrongQuestion);
            }
        }
    }

    @Override
    public Result autoMarking(List<PaperInfoVo> paperInfoVos) {
        //定义一个变量用来存储学生得到的分数
        score = 0;
        //定义一个变量用来存储用户编号
        int userId = 0;
        //定义一个变量存储试卷编号
        int paperId = 0;
        //定义简答题分数判断变量
        double jdaScore = 0;
        //首先遍历集合，判断是哪一种类型的题分值是多少
         for (PaperInfoVo paperInfoVo : paperInfoVos) {
             //给用户编号赋值
             userId = paperInfoVo.getUserId();
             //给试卷编号赋值
             paperId = paperInfoVo.getExamId();
             //1.单选题 2.多选题 3.判断题
             if (paperInfoVo.getTypeId() == 1 || paperInfoVo.getTypeId() == 2 || paperInfoVo.getTypeId() == 3){
                 compareAndScore(paperInfoVo,redisTemplate,100);
             }
             //4.简答题
             if (StringUtils.isNotBlank(paperInfoVo.getStuAnswer())){
                 if (paperInfoVo.getTypeId() == 4){
                     //将学生答案存入redis
                     redisTemplate.opsForSet().add(paperInfoVo.getUserId()+","+paperInfoVo.getExamId().toString()+","+paperInfoVo.getId(),paperInfoVo.getStuAnswer().toString());
                     //设置缓存过期时间为30天
                     redisTemplate.expire(paperInfoVo.getUserId()+","+paperInfoVo.getExamId().toString()+","+paperInfoVo.getId(), 30, TimeUnit.DAYS);
                     // 获取Redis中存储的答案集合
                     Set<Object> correctAnswers = redisTemplate.opsForSet().members(paperInfoVo.getId().toString());
                     // 简答题评分逻辑
                     String studentAnswer = paperInfoVo.getStuAnswer(); // 学生答案
                     String correctAnswer = correctAnswers.toString(); // 正确答案
                     // 计算答案相似度，这里假设使用编辑距离作为相似度度量
                     double similarity = calculateEditDistanceNormalized(studentAnswer, correctAnswer);
                     // 根据相似度给出评分
                     double scoreText = calculateScore(similarity);
                     // 更新试卷信息中的分数字段
                     score += scoreText;
                     jdaScore = scoreText;
                     //判断简答题分数小于3大于0之间的分数存入错题本
                     if (jdaScore < 3 && jdaScore > 0){
                         // 如果答案错误，则记录错题
                         SErrorBook sWrongQuestion = new SErrorBook();
                         sWrongQuestion.setQuestionId(paperInfoVo.getId());
                         sWrongQuestion.setUserId(paperInfoVo.getUserId());
                         sErrorBookMapper.insert(sWrongQuestion);
                     }
                 }
             }
         }
        //最后插入答题卡表
        SAnswer sAnswerCard = new SAnswer();
        sAnswerCard.setUId(userId);
        sAnswerCard.setCreateTime(new Date());
        sAnswerCard.setUpdateTime(new Date());
        sAnswerCard.setTestinfoId(paperId);
        sAnswerCard.setScope(score);
        sAnswerMapper.insert(sAnswerCard);
        return Result.OK(sAnswerCard.getScope());
    }

    @Override
    public Result historyExaminationInfo(SAnswerDto sAnswerDto) {
        PageHelper.startPage(sAnswerDto.getPageNum(), sAnswerDto.getPageSize());
        //查询答题卡表多表联查
        List<SAnswerExamInfoVo> sAnswers = sAnswerMapper.selectByUserId(sAnswerDto);
        //遍历集合
        for (SAnswerExamInfoVo sAnswer : sAnswers) {
            if (sAnswer.getRadioCount() != null &&
                    !sAnswer.getRadioCount().equals("") &&
                    sAnswer.getCheckCount() != null &&
                    !sAnswer.getCheckCount().equals("") &&
                    sAnswer.getJudgmentCount()!=null &&
                    !sAnswer.getJudgmentCount().equals("") &&
                    sAnswer.getTextCount() != null &&
                    !sAnswer.getTextCount().equals("")){
                //单选题总分
                String radioCount = sAnswer.getRadioCount();
                String[] radioParts = radioCount.split("_");
                int radioQuestionCount = Integer.parseInt(radioParts[0]);
                int radioQuestionScore = Integer.parseInt(radioParts[1]);
                //多选题总分
                String checkCount = sAnswer.getCheckCount();
                String[] checkParts = checkCount.split("_");
                int checkQuestionCount = Integer.parseInt(checkParts[0]);
                int checkQuestionScore = Integer.parseInt(checkParts[1]);
                //判断题总分
                String judgmentCount = sAnswer.getJudgmentCount();
                String[] judgmentParts = judgmentCount.split("_");
                int judgmentQuestionCount = Integer.parseInt(judgmentParts[0]);
                int judgmentQuestionScore = Integer.parseInt(judgmentParts[1]);
                //简答题总分
                String textCount = sAnswer.getTextCount();
                String[] textParts = textCount.split("_");
                int textQuestionCount = Integer.parseInt(textParts[0]);
                int textQuestionScore = Integer.parseInt(textParts[1]);
                //总分
                int totalScore = radioQuestionCount * radioQuestionScore + checkQuestionCount * checkQuestionScore + judgmentQuestionCount * judgmentQuestionScore + textQuestionCount * textQuestionScore;
                //设置总分
                sAnswer.setFullScore(totalScore);
                //及格分数是总分的80%
                sAnswer.setPassScore((int) (sAnswer.getFullScore() * 0.8));
            }
        }
        //返回分页结果
        PageInfo<SAnswerExamInfoVo> pageInfo = new PageInfo<>(sAnswers);
        return Result.OK(pageInfo);
    }

    @Override
    public Result historyExaminationQuestion(Integer userId, Integer examinationId) {
        // 查询历史考试题目
        List<PaperInfoVo> paperInfoVos = tUserMapper.examinationQuestion(examinationId);
        // 判断集合是否为空
        if (paperInfoVos == null || paperInfoVos.isEmpty() || paperInfoVos.size() == 0) {
            return Result.ERROR("未找到相关考试题目");
        }
        // 遍历集合
        for (PaperInfoVo paperInfoVo : paperInfoVos) {
            // 对三个参数进行非空验证
            if (userId == null || examinationId == null || paperInfoVo.getId() == null) {
                return Result.ERROR("参数不能为空");
            }
            Set<Object> members = redisTemplate.opsForSet().members(userId + "," + examinationId + "," + paperInfoVo.getId());
            if (members != null) {
                paperInfoVo.setStuAnswer(members.toString());
            }
        }
        return Result.OK(paperInfoVos);
    }

    @Override
    public Result selectClassById(Integer classId) {
        //通过班级id查询信息
        List<ClassVo> sClass = sClassMapper.selectByIdClass(classId);
        return Result.OK(sClass);
    }

    //定义一个空集合存储最新的查询数据
    List<ClassVo> classVos = new ArrayList<>();
    @Override
    public Result selectClassByStage(ClassVo classVo) {
        // 清除集合数据
        classVos.clear();
        boolean hasQueryCondition = false;
        if (classVo.getBeginTime()!= null &&!classVo.getBeginTime().isEmpty()
                || classVo.getName()!= null || classVo.getClassId()!= null) {
            hasQueryCondition = true;
        }
        int pageNum = classVo.getPageNum();
        int pageSize = classVo.getPageSize();
        if (hasQueryCondition) {
            // 如果有查询条件，设置较大的页码和页大小，以获取所有相关数据
            pageNum = 1;
            pageSize = Integer.MAX_VALUE;
        }
        PageHelper.startPage(pageNum, pageSize);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        if (classVo.getBeginTime()!= null &&!classVo.getBeginTime().isEmpty()){
            try {
                String beginTime = classVo.getBeginTime();
                Date date = dateFormat.parse(beginTime);
                Date endDate = new Date(date.getTime() + 24 * 60 * 60 * 1000);
                classVo.setBeginTime(dateFormat.format(endDate));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        List<ClassVo> sClass = sClassMapper.selectByStage(classVo);
        classVos.addAll(sClass);
        PageInfo<ClassVo> pageInfo = new PageInfo<>(sClass);
        return Result.OK(pageInfo);
    }

    @Override
    public void downloadDay(HttpServletResponse response) throws IOException {
        //定义一个空集合
        List<ClassVo> list = new ArrayList<>();
        //将上面查询的最新数据添加到集合中
        list.addAll(classVos);
        list.forEach(System.err::println);
        // 设置响应内容类型为 Excel 文件
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 对文件名进行编码处理
        String fileName = URLEncoder.encode("学生成绩", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        // 使用 EasyExcel 将数据写入输出流
        EasyExcel.write(response.getOutputStream(), ClassVo.class).sheet("学生成绩").doWrite(list);
    }

    //定时任务每个月执行一次
    @Scheduled(cron = "0 0 0 1 * *")
    public void deleteExpiredPapers() {
        //定义一个集合，存放需要删除的试卷id
        List<Integer> paperIds = new ArrayList<>();
        //查询历史考试信息只能查看一个月之内的
        List<SAnswer> sAnswers = sAnswerMapper.selectList(null);
        for (SAnswer sAnswer : sAnswers) {
            //删除答题卡创建时间在一个月之内的数据
            if (sAnswer.getCreateTime().getTime() < System.currentTimeMillis() - 30 * 24 * 60 * 60 * 1000) {
                paperIds.add(sAnswer.getId());
            }
        }
        //删除试卷信息
        try {
            sAnswerMapper.deleteBatchIds(paperIds);
        } catch (Exception e) {
            // 可以在这里打印更详细的错误信息或进行其他错误处理
            System.err.println("删除试卷信息时发生错误: " + e.getMessage());
        }
    }
}